//
//  RACSubjectVC.m
//  ReactiveObjCDemo
//
//  Created by xth on 2017/12/7.
//  Copyright © 2017年 xth. All rights reserved.
//

#import "RACSubjectVC.h"
#import "RACSubjectBVC.h"

@interface RACSubjectVC ()

@end

@implementation RACSubjectVC

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self createSubject];
    
    [self createReplaySubject];
    
    [self setupUI];
}

//RACSubject:信号提供者，自己可以充当信号，又能发送信号，使用场景：通常用来代替代理

//RACSubject使用步骤
//1.创建信号 [RACSubject subject]，跟RACSignal不一样，创建信号block
//2.订阅信号 subject subscribeNext
//3.发送信号 sendNext

// RACSubject:底层实现和RACSignal不一样。
// 1.调用subscribeNext订阅信号，只是把订阅者保存起来，并且订阅者的nextBlock已经赋值了。
// 2.调用sendNext发送信号，遍历刚刚保存的所有订阅者，一个一个调用订阅者的nextBlock。

//RACSubject实例进行map操作之后, 发送完毕一定要调用-sendCompleted, 否则会出现内存泄漏; 而RACSignal实例不管是否进行map操作, 不管是否调用-sendCompleted, 都不会出现内存泄漏.
//原因 : 因为RACSubject是热信号, 为了保证未来有事件发生的时候, 订阅者可以收到信息, 所以需要对持有订阅者!
- (void)createSubject {
    
    RACSubject *subject = [RACSubject subject];
    
    [subject sendNext:@"逗比"];
    
    [subject sendCompleted];
    
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"订阅者1的值：%@", x);
    }];
    
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"订阅者2的值：%@", x);
    }];
    
    [subject sendNext:@"cnblogs"];
}


- (void)setupUI {
    
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 50)];
    button.backgroundColor = [UIColor orangeColor];
    [button setTitleColor:[UIColor whiteColor] forState:0];
    [button setTitle:@"爱我就点我" forState:0];
    
    [self.view addSubview:button];
    
    [[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        
        RACSubjectBVC *vc = [RACSubjectBVC new];
        
        vc.delegateSignal = [RACSubject subject];
        
        [vc.delegateSignal subscribeNext:^(id  _Nullable x) {
            NSLog(@"%@", x);
        }];
        
        [self.navigationController pushViewController:vc animated:YES];
    }];

}



//RACReplaySubject 创建方法：
//（1）创建RACSubject
//（2）订阅信号
//（3）发送信号
//工作流程：
//（1）订阅信号时，内部保存了订阅者，和订阅者响应block
//（2）当发送信号的，遍历订阅者，调用订阅者的nextBlock
//（3）发送的信号会保存起来，当订阅者订阅信号的时，会将之前保存的信号，一个一个

//重复提供信号类，RACSubject的子类
//使用场景一:如果一个信号每被订阅一次，就需要把之前的值重复发送一遍，使用重复提供信号类
//使用场景二:可以设置capacity数量来限制缓存的value的数量,即只缓充最新的几个值


-(void)createReplaySubject
{
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"1 %@",x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"1 %@",x);
    }];
    [replaySubject sendNext:@1];
    
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"3 %@",x);
    }];
    
    //输出
    //    1 1,type:__NSCFNumber
    //    1 1,type:__NSCFNumber
    //    3 1,type:__NSCFNumber
    //    说明：RACSubject必须要先订阅信号之后才能发送信号，而RACReplaySubject可以先发送信号后订阅.
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
